home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher1.12 / misc / Radio / radio / foo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-14  |  9.9 KB  |  447 lines

  1. #include "gopher.h"
  2.  
  3.  
  4. /*
  5.  * Connect_To_Gopher Performs a connecting to socket 'service' on host
  6.  * 'host'.  Host can be a hostname or ip-address.  If 'host' is null, the
  7.  * local host is assumed.   The parameter full_hostname will, on return,
  8.  * contain the expanded hostname (if possible).  Note that full_hostname is a
  9.  * pointer to a char *, and is allocated by connect_to_gopher()
  10.  *
  11.  * Errors:
  12.  *
  13.  * -1 get service failed
  14.  *
  15.  * -2 get host failed
  16.  *
  17.  * -3 socket call failed
  18.  *
  19.  * -4 connect call failed
  20.  */
  21.  
  22. int connect_to_gopher(host)
  23.   char *host;
  24. {
  25.      int s, service;
  26.      char  buf[MAXSTR];
  27.      struct sockaddr_in server;
  28.      struct hostent *hp;
  29.  
  30.      service = 7000;
  31.      
  32.      if (host == '\0') {
  33.       gethostname(buf, sizeof(buf));
  34.       host = buf;
  35.      }
  36.  
  37.      if ((server.sin_addr.s_addr = inet_addr(host)) == -1) {
  38.       if (hp = gethostbyname(host)) {
  39.            bzero((char *) &server, sizeof(server));
  40.            bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length);
  41.            server.sin_family = hp->h_addrtype;
  42.       } else
  43.            return (-2);
  44.      } else
  45.       server.sin_family = AF_INET;
  46.  
  47.      server.sin_port = (unsigned short) htons(service);
  48.  
  49.      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  50.       return (-3);
  51.  
  52.      setsockopt(s, SOL_SOCKET, ~SO_LINGER, 0, 0);
  53.      setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 0, 0);
  54.      setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
  55.      if (connect(s, &server, sizeof(server)) < 0) {
  56.       close(s);
  57.       return (-4);
  58.      }
  59.      return s;
  60. }
  61.  
  62.  
  63. /*
  64. ** Feed a gopher takes a line of text and parses it.
  65. ** It returns a 0 when successful and -1 when it isn't
  66. */
  67.  
  68. int
  69. feed_a_gopher(j, sInput)
  70.   int j;
  71.   char *sInput;
  72. {
  73.      int i;
  74.      char *cPtr = NULL;
  75.      
  76.      char *CurrentChar = NULL;
  77.      i=sizeof(GopherThing);
  78.      /*memset(Gopher[j], 0, i);  Causes weird bug in A/UX*/
  79.      
  80.      
  81.      /** Get the kind of file from the first character **/
  82.  
  83.      Gopher[j].sFileType = sInput[0];
  84.      
  85.      if(Gopher[j].sFileType == A_EOI)
  86.       return(0);
  87.  
  88.      /** Suck off the User Displayable name **/
  89.      
  90.      cPtr = (char *) strchr(sInput, '\t');
  91.      if (cPtr == NULL)
  92.       return(-1);
  93.      *cPtr = '\0'; 
  94.      strncpy(Gopher[j].sTitle, sInput + 1, (int) (cPtr-sInput+1));
  95.      sInput = cPtr + 1;
  96.  
  97.      /** Suck off the Pathname **/
  98.  
  99.      cPtr = strchr(sInput, '\t');
  100.      if (cPtr == NULL)
  101.       return(-1);
  102.      *cPtr = '\0'; 
  103.      strncpy(Gopher[j].sPath, sInput , (int) (cPtr-sInput+1));
  104.      sInput = cPtr + 1;
  105.  
  106.      /** Suck off the hostname **/
  107.  
  108.      cPtr = strchr(sInput, '\t');
  109.      if (cPtr == NULL)
  110.       return(-1);
  111.      *cPtr = '\0'; 
  112.      strncpy(Gopher[j].sHost, sInput, (int) (cPtr-sInput+1));
  113.      sInput = cPtr + 1;
  114.  
  115.      Gopher[j].iPort = 0;
  116.  
  117.      /** Get the port number **/
  118.      if (isdigit(*sInput) && isdigit(*(sInput+1)))
  119.       Gopher[j].iPort = atoi(sInput);
  120.      else
  121.       Gopher[j].iPort = 0;
  122.  
  123.      return(0);
  124. }
  125.  
  126. /*
  127. **
  128. **
  129. */
  130.  
  131.    
  132. int feed_gophers(sockfd)
  133.   int sockfd;
  134. {
  135.      int i, j, k;
  136.      FILE *fp;
  137.      char ch, sTmp[sizeof(GopherThing)];
  138.      
  139.      writestring(sockfd, "\r\n");
  140.      
  141.      for (j = 0; (j < MAXGOPHERS) && (ch != EOF) && (sTmp[0] != '.'); j++)
  142.      {
  143.       bzero(sTmp, sizeof(GopherThing));
  144.       if (readline(sockfd, sTmp, sizeof(GopherThing)) == 0)
  145.            break;
  146.       
  147.       if (feed_a_gopher(j, sTmp)!=0)
  148.            j = j -1;  /** feed a gopher failed, try again **/
  149.      }
  150.      
  151.      return(j-1);
  152.  
  153. /*
  154. ** Open a connection to another host
  155. */
  156.  
  157.  
  158. do_telnet(iNum)
  159.   int iNum;
  160. {
  161.      char Tel_string1[128];
  162.      char Tel_string2[128];
  163.      char TelCommand[128]; 
  164.      char ch;
  165.  
  166.      /* retrieve the gopher information for the telnet command*/
  167.  
  168.      clear();
  169.      Centerline("Warning!!!!!, you are about to leave the Internet", 1);
  170.      Centerline("Gopher program and connect to another host.", 2);
  171.      Centerline("If you get stuck press the control key and the ] key,",3);
  172.      Centerline("and then type quit",4);
  173.      
  174.      sprintf(Tel_string1,"Now connecting to %s", Gopher[iNum].sHost);
  175.      if (Gopher[iNum].sPath[0] != '\0')
  176.       sprintf(Tel_string2,"Use the account name \"%s\" to log in",
  177.           Gopher[iNum].sPath);
  178.      else
  179.       Tel_string2[0] = '\0';
  180.  
  181.      Centerline(Tel_string1, LINES/2 -1);
  182.      Centerline(Tel_string2, LINES/2 +1);
  183.      Centerline("Press return to connect: ", LINES - 1);
  184.      refresh();
  185.  
  186.      while ((ch = getch()) != '\r')
  187.       ;
  188.  
  189.      exit_curses();
  190.  
  191.      strcpy(TelCommand, TELNET_COMMAND);
  192.      strcat(TelCommand, " ");
  193.      strcat(TelCommand, Gopher[iNum].sHost);
  194.  
  195.      if (Gopher[iNum].iPort != 0) 
  196.       sprintf((TelCommand + strlen(TelCommand)), " %d",Gopher[iNum].iPort); 
  197.  
  198.      system(TelCommand);
  199.      init_curses();
  200. }
  201.  
  202.  
  203. /*
  204. ** do_index gets keywords from the user to search for, and jams the
  205. ** string into the sPath part of the GopherThing Structure.
  206. */
  207.  
  208. do_index(iNum)
  209.   int iNum;
  210. {
  211.      char inputline[40];
  212.  
  213.      inputline[0] = '\0';
  214.      GetOneOption("Index word(s) to search for: ", inputline);
  215.      strcpy(Gopher[iNum].sPath, inputline);
  216. }
  217.  
  218.      
  219. /**
  220. *** Show file takes an open socket connection, writes it to a file
  221. *** and passes it to your favorite pager.
  222. **/
  223.  
  224. showfile(sockfd, iNum)
  225.   int sockfd, iNum;
  226. {
  227.      int i, iLength, childpid, wait_stat, wait_ret;
  228.      char *cp;
  229.      char tmpfilename[40];
  230.      char *tmpptr = tmpfilename;
  231.      FILE *tmpfile;
  232.      char inputline[512];
  233.      char Command[100]; 
  234.  
  235.      Draw_Status("Receiving Document...");   
  236.      refresh();
  237.  
  238.      /** Open a temporary file **/
  239.  
  240.      sprintf(tmpfilename, "/tmp/gopher.%d",getpid());
  241.  
  242.      if ((tmpfile = fopen(tmpfilename, "w")) == NULL)
  243.       fprintf(stderr, "Couldn't make a tmp file!\n"), exit(-1);
  244.  
  245.      writestring(sockfd, Gopher[iNum].sPath, strlen(Gopher[iNum].sPath));
  246.      writestring(sockfd, "\r\n", 2);
  247.  
  248.      for(;;) {
  249.       iLength = readline(sockfd, inputline, 512);
  250.       
  251.       if (iLength == 0)
  252.            break;
  253.  
  254.       ZapCRLF(inputline);
  255.       
  256.           if (Gopher[iNum].sFileType == A_CSO) {
  257.            if (inputline[0] == '2')
  258.             break;
  259.  
  260.            if ((inputline[0] >= '3') && (inputline[0] <= '9'))  {
  261.             fprintf(tmpfile, "%s\n", Gopher[iNum].sPath);
  262.             fprintf(tmpfile, "%s\n", inputline+4);
  263.             break;
  264.            }
  265.            if (inputline[0] == '-') {
  266.             if (inputline[5] != i)
  267.              fprintf(tmpfile, "-------------------------------------------------------\n");
  268.             i = inputline[5];
  269.             fprintf(tmpfile, "%s\n", inputline+7);
  270.            }
  271.       }
  272.  
  273.           if (Gopher[iNum].sFileType == A_FILE) {
  274.            if ((inputline[0] == '.') && (inputline[1] == '\0'))
  275.             break;
  276.            else {
  277.             fprintf(tmpfile, "%s\n", inputline);
  278.            }
  279.       }
  280.      }
  281.  
  282.      fprintf(tmpfile, "\012 \n\n");  /** Work around a bug in xterm n curses*/
  283.      (void)fclose(tmpfile);
  284.  
  285.      display_file(tmpfilename);
  286.  
  287.      /** Good little clients clean up after themselves..**/
  288.  
  289.      if (unlink(tmpfilename)!=0)
  290.       fprintf(stderr, "Couldn't unlink!!!\n"), exit(-1);
  291.  
  292.      init_curses();
  293. }
  294.  
  295.  
  296. pushgopher(iLevel, iNum)
  297.   int iLevel, iNum;
  298. {
  299.      OldGopher[iLevel].sFileType = A_DIRECTORY;
  300.      strcpy(OldGopher[iLevel].sTitle, Gopher[iNum].sTitle);
  301.      strcpy(OldGopher[iLevel].sHost, Gopher[iNum].sHost);
  302.      strcpy(OldGopher[iLevel].sPath, Gopher[iNum].sPath);
  303.      OldGopher[iLevel].iPort = Gopher[iNum].iPort;
  304. }
  305.  
  306. popgopher(iLevel, iNum)
  307.   int iLevel, iNum;
  308. {
  309.      Gopher[iNum].sFileType = A_DIRECTORY;
  310.      strcpy(Gopher[iNum].sTitle, OldGopher[iLevel].sTitle);
  311.      strcpy(Gopher[iNum].sHost, OldGopher[iLevel].sHost);
  312.      strcpy(Gopher[iNum].sPath, OldGopher[iLevel].sPath);
  313.      Gopher[iNum].iPort = OldGopher[iLevel].iPort;
  314. }
  315.  
  316.  
  317. void check_sock(sockfd, iNum)
  318.   int sockfd, iNum;
  319. {
  320.      char DispString[80];
  321.      char Response[40];
  322.  
  323.      Response[0] = '\0';
  324.      
  325. #ifdef DEBUG
  326.      switch(sockfd)  {
  327.      case -4:
  328.       fprintf(stderr, "connect call failed ");
  329.       break;
  330.      case -3:
  331.       (void)fprintf(stderr, "socket call failed");
  332.       break;
  333.      case -2:
  334.       (void)fprintf(stderr, "get host failed");
  335.       break;
  336.      case -1:
  337.       (void)fprintf(stderr, "get service failed");
  338.       break;
  339.      }
  340.      fprintf(stderr, "to host %s, port %d\n",
  341.          Gopher[iNum].sHost, Gopher[iNum].iPort);
  342.      exit(-1);
  343. #endif
  344.  
  345.      if (sockfd <0) {
  346.       sprintf(DispString, "Cannot connect to host %s", Gopher[iNum].sHost);
  347.       GetOneOption(DispString, Response);
  348.      }
  349. }
  350.  
  351.  
  352. /**********
  353. **
  354. ** Set up all the global variables.
  355. **
  356. ***********/
  357.  
  358. void
  359. Initialize()
  360. {
  361.      int i,err;
  362.      char *cp;
  363.      char termname[40];
  364.      static char terminal[1024];
  365.      static char capabilities[1024];   /* String for cursor motion */
  366.      
  367.      static char *ptr = capabilities;  /* for buffering         */
  368.  
  369.      /** Get the pager command **/
  370.      
  371.      if (getenv("PAGER") == NULL)
  372.       strcpy(PagerCommand, PAGER_COMMAND);
  373.      else
  374.       strcpy(PagerCommand, getenv("PAGER"));
  375.  
  376.      /*** Get the terminal type ***/
  377.  
  378.      if (getenv("TERM") == NULL)
  379.       fprintf(stderr, "I don't understand your terminal type\n"), exit(-1);
  380.      
  381.      if (strcpy(termname, getenv("TERM")) == NULL)
  382.       fprintf(stderr, "I don't understand your terminal type\n"),exit(-1);
  383.      
  384.      if ((err = tgetent(terminal, termname)) != 1)
  385.       fprintf(stderr, "I don't understand %s terminals\n",termname),exit(-1);
  386.      
  387.      if ((cp = (char *)tgetstr("cl", &ptr)) != NULL)
  388.       strcpy(sGClearscreen, cp);
  389.      else
  390.       strcpy(sGClearscreen, "");
  391.  
  392.      if ((cp = (char *) tgetstr("bl", &ptr)) != NULL)
  393.       strcpy(sGAudibleBell, cp);
  394.      else
  395.       strcpy(sGAudibleBell,"\007");
  396.  
  397.      /*** Init MainWindow ****/
  398.  
  399.  
  400.      tputs(sGClearscreen,1, outchar);     
  401.  
  402.      MainWindow = initscr();
  403. }
  404.  
  405.  
  406. char *GlobalOptions[] =  
  407. {"Pager Command", "Print Command", "Telnet Command"};
  408.                
  409.  
  410. void
  411. SetOptions()
  412. {
  413.      char Response[3][40];
  414.      
  415.      strcpy(Response[0], PagerCommand);
  416.      Get_Options("Internet Gopher Options", "", 3, GlobalOptions, Response);
  417.  
  418.      strcpy(PagerCommand, Response[0]);
  419. }
  420.  
  421. #define BUFSIZE 256
  422.  
  423. main(argc, argv)
  424.   int argc;
  425.   char *argv[];
  426. {
  427.      int sockfd, j, i;
  428.      char buf[BUFSIZE];
  429.      FILE *Play;
  430.      char Playcmd[80];
  431.  
  432.      sprintf(Playcmd, "play %s", argv[2]);
  433.  
  434.      Play = popen(Playcmd, "w");
  435.  
  436.      sockfd = connect_to_gopher(argv[1]);
  437.  
  438.      while(1) {
  439.       j = read(sockfd, buf, BUFSIZE);
  440.       for (i=0; i<j; i++)
  441.            putc(buf[i], Play);
  442.  
  443.      }
  444.       
  445. }
  446.